package com.ruoyi.net.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.net.domain.*;
import com.ruoyi.net.netconf.util.DeviceManager;
import com.ruoyi.net.service.IElementPortEthService;
import com.ruoyi.net.service.IElementPortMtnFgService;
import com.ruoyi.net.service.INetElementService;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictTypeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.net.mapper.ElementPortModeMapper;
import com.ruoyi.net.service.IElementPortModeService;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 网元-接口-模式配置Service业务层处理
 * 
 * @author net
 * @date 2024-11-17
 */
@Service
public class ElementPortModeServiceImpl implements IElementPortModeService 
{
    @Autowired
    private ElementPortModeMapper elementPortModeMapper;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private INetElementService netElementService;

    @Autowired
    private DeviceManager deviceManager;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private IElementPortEthService elementPortEthService;

    @Autowired
    private IElementPortMtnFgService elementPortMtnFgService;

    /**
     * 查询网元-接口-模式配置
     * 
     * @param id 网元-接口-模式配置主键
     * @return 网元-接口-模式配置
     */
    @Override
    public ElementPortMode selectElementPortModeById(String id)
    {
        return elementPortModeMapper.selectElementPortModeById(id);
    }

    /**
     * 查询网元-接口-模式配置列表
     * 
     * @param elementPortMode 网元-接口-模式配置
     * @return 网元-接口-模式配置
     */

    @Override
    public List<ElementPortMode> selectElementPortModeList(ElementPortMode elementPortMode) {
        return elementPortModeMapper.selectElementPortModeList(elementPortMode);
    }

    @Override
    public List<ElementPortMode> selectElementPortModeListOnly(ElementPortMode elementPortMode) {
        return elementPortModeMapper.selectElementPortModeListOnly(elementPortMode);
    }

    @Override
    public List<ElementPortMode> init(ElementPortMode elementPortMode) {
        List<ElementPortMode> elementPortModes = new ArrayList<>();
        if (StringUtils.isEmpty(elementPortMode.getElementId())) {
            return elementPortModes;
        }
//        List<ElementPortMode> readElements = readDevice(elementPortMode);
        // 从 dict_element_mode_init 字典读取初始化端口信息
        List<ElementPortMode> readElements = readElementModesFromDict();
        List<ElementPortMode> dbElements = elementPortModeMapper.selectElementPortModeList(elementPortMode);

        // 不相同
        List<ElementPortMode> uncommonElements = readElements.stream().filter(readBack -> dbElements.stream()
                        .noneMatch(dbElement -> readBack.getPortName().substring(StringUtils.indexOfAny(readBack.getPortName(), "/") - 1)
                                .equalsIgnoreCase(dbElement.getPortName().substring(StringUtils.indexOfAny(dbElement.getPortName(), "/") - 1))))
                .collect(Collectors.toList());

        for (ElementPortMode uncommonElement : uncommonElements) {
            uncommonElement.setId(IdUtils.simpleUUID());
//            uncommonElement.setStatus("0");
            uncommonElement.setElementId(elementPortMode.getElementId());
            uncommonElement.setCreateBy(SecurityUtils.getUsername());
            uncommonElement.setCreateTime(DateUtils.getNowDate());
            elementPortModeMapper.insertElementPortMode(uncommonElement);
        }

        // 初始化以太、Fg
        ElementPortEth eth = new ElementPortEth();
        eth.setElementId(elementPortMode.getElementId());
        ElementPortMtnFg fg = new ElementPortMtnFg();
        fg.setElementId(elementPortMode.getElementId());
        List<ElementPortEth> readPortEths = elementPortEthService.selectElementPortEthList(eth);
        List<ElementPortMtnFg> readPortMtnFgs = elementPortMtnFgService.selectElementPortMtnFgList(fg);
        for (ElementPortMode readElement : readElements) {
            // 以太
            if ("enable".equals(readElement.getPortMode())) {
                ElementPortEth portEth = new ElementPortEth();
                portEth.setElementId(elementPortMode.getElementId());
                portEth.setTerminalName(readElement.getPortName());
                portEth.setPortName(readElement.getPortName());

                if (readPortEths.isEmpty() ||
                        readPortEths.stream()
                                .noneMatch(a -> a.getPortName().equalsIgnoreCase(readElement.getPortName()))) {
                    portEth.setStatus("0");
                    elementPortEthService.insertElementPortEth(portEth);
                }
            }
            else { // Fg
                ElementPortMtnFg portMtnFg = new ElementPortMtnFg();
                portMtnFg.setElementId(elementPortMode.getElementId());
                portMtnFg.setTerminalName(readElement.getPortName());

                if (readPortMtnFgs.isEmpty() ||
                        readPortMtnFgs.stream().noneMatch(a -> a.getTerminalName().equalsIgnoreCase(readElement.getPortName()))) {
                    portMtnFg.setStatus("0");
                    elementPortMtnFgService.insertElementPortMtnFg(portMtnFg);
                }
            }
        }
        /*

        List<ElementPortMode> commonElements = readElements.stream().filter(readBack -> dbElements.stream()
                        .anyMatch(dbElement -> readBack.getPortName().substring(StringUtils.indexOfAny(readBack.getPortName(), "/") - 1)
                                .equalsIgnoreCase(dbElement.getPortName().substring(StringUtils.indexOfAny(dbElement.getPortName(), "/") - 1))))
                .collect(Collectors.toList());
        // 相同
        for (ElementPortMode commonElement : commonElements) {
            List<ElementPortMode> dbElementOri = dbElements.stream().filter(dbElement -> dbElement.getPortName().substring(StringUtils.indexOfAny(dbElement.getPortName(), "/") - 1)
                    .equalsIgnoreCase(commonElement.getPortName().substring(StringUtils.indexOfAny(commonElement.getPortName(), "/") - 1))).collect(Collectors.toList());
            commonElement.setId(dbElementOri.get(0).getId());
            commonElement.setStatus("1");
            commonElement.setElementId(elementPortMode.getElementId());
            commonElement.setCreateBy(SecurityUtils.getUsername());
            commonElement.setCreateTime(DateUtils.getNowDate());
            elementPortModeMapper.updateElementPortMode(commonElement);
        }*/
        return elementPortModeMapper.selectElementPortModeList(elementPortMode);
    }

    /**
     * 从字典读取初始化网元端口信息
     * @return
     */
    private List<ElementPortMode> readElementModesFromDict() {
        List<ElementPortMode> elementPortModes = new ArrayList<>();
        List<SysDictData> initElements = dictTypeService.selectDictDataByType(CacheConstants.INIT_ELEMENT_PORT);
        for (SysDictData elementPort : initElements) {

            ElementPortMode entity = new ElementPortMode();
            entity.setPortName(elementPort.getDictLabel());
            entity.setStatus("enable".equalsIgnoreCase(elementPort.getCssClass()) ? "1" : "0");
            entity.setPortMode(elementPort.getCssClass());
            elementPortModes.add(entity);
        }
        return elementPortModes;
    }

    /**
     * 读取端口信息
     * @param elementPortMode
     * @return
     */
    private List<ElementPortMode> readDevice(ElementPortMode elementPortMode) {
        List<ElementPortMode> elementPortModes = new ArrayList<>();
        StringBuilder xml = new StringBuilder();
        xml.append(
                "<if xmlns=\"http://fiberhome.com/fhnw/yang/interface/fos-interface-common\">" +
                        "    <interfaces>" +
                        "      <interface xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" +
//                        "        <type>ETH-PHY</type>" +
//                        "        <enabled>enable</enabled>" +
                        "      </interface>" +
                        "    </interfaces>" +
                        "  </if>");
        NetElement netElement = netElementService.getCacheObject(elementPortMode.getElementId());
        if (sysConfigService.selectDebugEnabled()) {
            deviceManager.getDevice(netElement.getIp());
            String rpcReply = deviceManager.getConfig(xml.toString());

            // 解析xml
            NodeList list = XmlUtils.findNetConfXmlNodes(rpcReply, "//interfaces/interface");
            if (list != null && list.getLength() > 0) {
                for (int i = 0; i < list.getLength(); i++) {
                    ElementPortMode entity = new ElementPortMode();
                    Node node = list.item(i);
                    // 通过标签名获取节点的值
                    String portType = XmlUtils.getXmlLabelValue(node, "type");
                    entity.setPortName(XmlUtils.getXmlLabelValue(node, "name"));
                    entity.setStatus("1"); // 从设备读取到的配置，设置状态为激活
                    if (portType.equalsIgnoreCase("eth-phy") || portType.equalsIgnoreCase("mtn-fgphy")) {
                        entity.setPortMode(portType.equalsIgnoreCase("eth-phy") ? "enable" : "disable");
                        elementPortModes.add(entity);
                    }
                }
            }
        }
        return elementPortModes;
    }

    /**
     * 新增网元-接口-模式配置
     * 
     * @param elementPortMode 网元-接口-模式配置
     * @return 结果
     */
    @Override
    public int insertElementPortMode(ElementPortMode elementPortMode)
    {
        String uuid = IdUtils.simpleUUID();
        if (StringUtils.isEmpty(elementPortMode.getId())) {
            elementPortMode.setId(uuid);
        }
        ElementPortMode elementPortModeSearch = new ElementPortMode();
        elementPortModeSearch.setElementId(elementPortMode.getElementId());
        elementPortModeSearch.setPortName(elementPortMode.getPortName());
        if (elementPortModeMapper.selectElementPortModeList(elementPortModeSearch).size() > 0) {
            throw new RuntimeException("网元-接口-模式配置已存在");
        }
        elementPortMode.setCreateBy(SecurityUtils.getUsername());
        elementPortMode.setCreateTime(DateUtils.getNowDate());
        elementPortMode.setUpdateBy(SecurityUtils.getUsername());
        elementPortMode.setUpdateTime(DateUtils.getNowDate());
        return elementPortModeMapper.insertElementPortMode(elementPortMode);
    }

    /**
     * 修改网元-接口-模式配置
     * 
     * @param elementPortMode 网元-接口-模式配置
     * @return 结果
     */
    @Override
    public int updateElementPortMode(ElementPortMode elementPortMode)
    {
        elementPortMode.setUpdateBy(SecurityUtils.getUsername());
        elementPortMode.setUpdateTime(DateUtils.getNowDate());
        return elementPortModeMapper.updateElementPortMode(elementPortMode);
    }

    /**
     * 批量删除网元-接口-模式配置
     * 
     * @param ids 需要删除的网元-接口-模式配置主键
     * @return 结果
     */
    @Override
    public int deleteElementPortModeByIds(String[] ids)
    {
        return elementPortModeMapper.deleteElementPortModeByIds(ids);
    }

    /**
     * 删除网元-接口-模式配置信息
     * 
     * @param id 网元-接口-模式配置主键
     * @return 结果
     */
    @Override
    public int deleteElementPortModeById(String id)
    {
        return elementPortModeMapper.deleteElementPortModeById(id);
    }

    @Override
    public int updateElementPortModeStatus(String[] names, String status) {
        return elementPortModeMapper.updateElementPortModeStatus(names, status);
    }
}
